window.onload = function() {

	function checkInitializedCharacterPageWatchers(scope) {
		expect(typeof scope.safeApply).toBe('function');

		expect(scope.character).toEqual({});
		expect(scope.attributeArray).toEqual([]);
		expect(scope.saveBonusArray).toEqual([]);
		expect(scope.skillArray).toEqual([]);
		expect(scope.featCategoryArray).toEqual([]);

		expect(typeof scope.back).toBe('function');
		expect(typeof scope.forward).toBe('function');
	}

	describe('Regular Controllers', function() {

		describe('MockController', function() {
			it('should not change the scope at all', function() {
				var scope = {};

				Ender.Game.Controllers.MockController(scope);

				expect(scope).toEqual({});
			});
		});

		describe('ChoiceController', function() {

			it('should correctly initialize the rootChoice and currentChoice', function() {
				var choice = {}, scope = {}, routeParams = {}, gameRepository = {
					getChoiceById : function(id, func) {
						func(choice);
					}
				};

				Ender.Game.Controllers.ChoiceController(scope, routeParams, gameRepository);

				expect(scope.rootChoice).toBe(choice);
				expect(scope.currentChoice).toBe(choice);
			});

			it('should correctly set currentChoice', function() {
				var choice = {}, scope = {}, routeParams = {}, gameRepository = {
					getChoiceById : function(id, func) {
					}
				};

				Ender.Game.Controllers.ChoiceController(scope, routeParams, gameRepository);

				expect(scope.currentChoice).toBe(undefined);

				scope.setCurrentChoice(choice);

				expect(scope.currentChoice).toBe(choice);
			});

			it('should correctly go back', function() {
				var parentChoice = {}, choice = {
					parent : parentChoice
				}, scope = {}, routeParams = {}, gameRepository = {
					getChoiceById : function(id, func) {
						func(choice);
					}
				};

				Ender.Game.Controllers.ChoiceController(scope, routeParams, gameRepository);

				scope.back();

				expect(scope.currentChoice).toBe(parentChoice);

				scope.back();

				expect(scope.currentChoice).toBe(choice);
			});

		});

		describe('CharacterController', function() {
			it('should initialize character page watchers', function() {
				var scope = {
					$watch : function() {
					}
				}, routeParams = {}, gameRepository = {
					getCharacterById : function() {
					}
				};

				Ender.Game.Controllers.CharacterController(scope, routeParams, gameRepository);

				checkInitializedCharacterPageWatchers(scope);
			});

			it('should properly set character', function() {
				var scope = {
					$root : {
						$$phase : '$apply'
					},
					$watch : function() {
					}
				}, character = {}, routeParams = {}, gameRepository = {
					getCharacterById : function(id, func) {
						func(character);
					}
				};

				Ender.Game.Controllers.CharacterController(scope, routeParams, gameRepository);

				expect(scope.character).toBe(character);

			});

			it('should not go back and forward for tutorial characters', function() {
				var scope = {
					$root : {
						$$phase : '$apply'
					},
					$watch : function() {
					}
				}, character = {
					universe : 'tutorial'
				}, routeParams = {}, gameRepository = {
					getCharacterById : function(id, func) {
						func(character);
					}
				}, messagesShown = 0, popupService = {
					showMessage : function() {
						messagesShown++;
					}
				};

				Ender.Game.Controllers.CharacterController(scope, routeParams, gameRepository, popupService);

				var url = window.location;

				scope.back();
				scope.forward();

				expect(messagesShown).toEqual(2);
				expect(window.location).toEqual(url);

			});
		});

		describe('ArenaController', function() {
			it('should correctly initialize arena properties', function() {
				var scope = {}, rootScope = {
					chosenCharacter : {},
					generatedArena : {
						backgroundImage : "image",
						grid : [],
						placeCharacter : function() {
							// TODO mock test
						},
						getCharacters : function(){
							return [];
						},
						select : function(){
							
						},
						showReachableZoneFor : function(){
							// TODO mock test
						}
					}
				};

				Ender.Game.Controllers.ArenaController(scope, rootScope);

				expect(scope.arenaBackground).toEqual('url(image)');
				expect(scope.arenaGrid).toEqual([]);

			});
		});

	});

	describe('Tutorial Controllers', function() {

		describe('MeleeCharacterTutorialController', function() {

			it('should init tutorial', function() {

				var scope = {
					$watch : function() {
					},
					$on : function() {
					}
				}, rootScope = {
						
				}, gameRepository = {
					getCharacterById : function() {
					}
				}, tutorialMessageService = {
					showMessageSuite : function() {
					}
				};

				Ender.Game.Controllers.MeleeCharacterTutorialController(scope, rootScope, gameRepository, tutorialMessageService);

				checkInitializedCharacterPageWatchers(scope);
			});

			it('should show all messages', function() {

				var called = false;

				var scope = {
					$watch : function() {
					},
					$on : function() {
					}
				}, rootScope = {
						
				}, gameRepository = {
					getCharacterById : function() {
					}
				}, tutorialMessageService = {
					showMessageSuite : function(array) {
						called = true;
					}
				};

				Ender.Game.Controllers.MeleeCharacterTutorialController(scope, rootScope, gameRepository, tutorialMessageService);

				expect(called).toBe(Ender.Game.Settings.showTutorialMessages);
			});

		});

		describe('RangedCharacterTutorialController', function() {
			it('should init tutorial', function() {

				var scope = {
					$watch : function() {
					}
				}, gameRepository = {
					getCharacterById : function() {
					}
				}, popupService = {
					showMessage : function() {
					},
					showMessageWithOptions : function() {
					}
				};

				Ender.Game.Controllers.RangedCharacterTutorialController(scope, gameRepository, popupService);

				checkInitializedCharacterPageWatchers(scope);
			});
		});

		describe('StealthCharacterTutorialController', function() {
			it('should init tutorial', function() {

				var scope = {
					$watch : function() {
					}
				}, gameRepository = {
					getCharacterById : function() {
					}
				}, popupService = {
					showMessage : function() {
					},
					showMessageWithOptions : function() {
					}
				};

				Ender.Game.Controllers.StealthCharacterTutorialController(scope, gameRepository, popupService);

				checkInitializedCharacterPageWatchers(scope);
			});
		});

		describe('CasterCharacterTutorialController', function() {
			it('should init tutorial', function() {

				var scope = {
					$watch : function() {
					}
				}, gameRepository = {
					getCharacterById : function() {
					}
				}, popupService = {
					showMessage : function() {
					},
					showMessageWithOptions : function() {
					}
				};

				Ender.Game.Controllers.CasterCharacterTutorialController(scope, gameRepository, popupService);

				checkInitializedCharacterPageWatchers(scope);
			});
		});

	});

	// KICK OFF JASMINE
	var jasmineEnv = jasmine.getEnv();

	var trivialReporter = new jasmine.TrivialReporter();
	jasmineEnv.addReporter(trivialReporter);

	jasmineEnv.specFilter = function(spec) {
		return trivialReporter.specFilter(spec);
	};

	jasmineEnv.execute();

};